<?php

declare(strict_types=1);

namespace app\admin\service;

use app\admin\model\Images;
use app\admin\model\OrderPayment as OrderPaymentModel;
use app\admin\service\ProductInventory;
use app\common\BusinessLog;
use app\admin\model\Order as OrderModel;
use app\admin\model\WholesalOrder as WholesalOrderModel;
use app\admin\model\TransactionCurrency;
use app\api\service\PaymentMethod as PaymentMethod;
use app\admin\service\Inventory;
use app\admin\model\Inventory as InventoryModel;
use app\admin\model\Customer as CustomerModel;
use think\facade\Db;
use app\api\service\GoAffPro;
use app\common\service\Mail as MailService;
use think\facade\Log;
use app\common\service\Inventory as CommonInventoryService;
use app\common\service\DingTalk;
use app\common\service\CompleteNotificationService;
use app\common\ExcelService;


class OrderPayment extends BaseService
{
    /**
     * 注册服务
     *
     * @return mixed
     */
    public function register()
    {
        //
    }

    /**
     * 执行服务
     *
     * @return mixed
     */
    public function boot()
    {
        //
    }

    /**
     * 订单列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-11-13 14 31 10
     * author: jiang
     */
    public function index($param, int $page, int $limit)
    {
        $arrData = ['code' => 0, 'message' => 'success'];
        $where = [];


        if ($param['order_no']) {
            $where[] = ['order_no', 'like', '%' . $param['order_no'] . '%'];
        }
        if ($param['order_ids']) {
            $where[] = ['order_id', 'in', $param['order_ids']];
        }
        if ($param['voucher_code']) {
            $where[] = ['voucher_code', 'like', '%' . $param['voucher_code'] . '%'];
        }
        if ($param['order_type']) {
            $where[] = ['order_type', '=', $param['order_type']];
        }
        if ($param['pay_type']) {
            $where[] = ['pay_type', '=', $param['pay_type']];
        }
        if ($param['pay_status']) {
            $where[] = ['status', '=', $param['pay_status']];
        }
        if ($param['start_time']) {
            $where[] = ['pay_time', '>=', $param['start_time']];
        }
        if ($param['end_time']) {
            $where[] = ['pay_time', '<', $param['end_time']];
        }
        if ($param['invoice_status']) {
            $where[] = ['invoice_status', 'in', $param['invoice_status']];
        }
        if ($param['user_id']) {
            $where[] = ['user_id', 'in', $param['user_id']];
        }
        if ($param['creator']) {
            $where[] = ['creator', '=', $param['creator']];
        }

        $field = ['id', 'order_no', 'order_id', 'user_id', 'invoice_status', 'status', 'pay_amount', 'paid_amount', 'status as pay_status', 'pay_type', 'pay_currency', 'notes', 'pay_account', 'pay_code', 'payment_url', 'reviewer_time', 'pay_time', 'voucher_code', 'reviewer', 'order_type', 'transfer_voucher_id', 'payment_method', 'fee_type', 'transfer_type', 'creator', 'remark'];
        $oOrderPaymentModel = OrderPaymentModel::where($where);
        if ($param['invoive_id']) {
            $ids = \app\admin\model\Invoice::where('id', $param['invoive_id'])->value('payment_ids');
            $oOrderPaymentModel->whereOr('id', 'in', $ids);
        }
        $total = $oOrderPaymentModel->count();
        $result = $oOrderPaymentModel->with(['user', 'reviewer', 'creator'])->field($field)->page($page, $limit)->order('id', 'desc')->select();

        $data = $result->toArray();


        $orderArr = [];
        $whosealArr = [];
        $imgsArr = [];
        foreach ($data as $value) {
            if ($value['order_type'] == 'wholesal') {
                $whosealArr[] = $value['order_id'];
            } elseif ($value['order_type'] == 'order') {
                $orderArr[] = $value['order_id'];
            }
            if ($value['transfer_voucher_id']) {
                $imgsArr = array_merge($imgsArr, explode(',', $value['transfer_voucher_id']));
            }
        }


        $imgsArr = array_unique($imgsArr);

        $oImages = Images::whereIn('id', $imgsArr)->column('id,url');
        $imgsDict = [];
        foreach ($oImages as $item) {
            $imgsDict[$item['id']] = 'https://' . config('filesystem.aliyun-oss.bucket') . '.' . config('filesystem.aliyun-oss.endpoint') . '/' . $item['url'];
        }

        $orderData = OrderModel::where('id', 'in', $orderArr)->where('is_del', 0)->column('id,total_amount,status as order_status,currency,total_amount as order_total_amount,pay_amount as order_pay_amount,owner');
        $orderDict = [];
        foreach ($orderData as $item) {
            $orderDict[$item['id']] = $item;
            // 收集owner的ID
            if (!empty($item['owner'])) {
                $operatorIds[] = $item['owner'];
            }
        }
        $oOrderModel = new OrderModel();

        $wholesalData = WholesalOrderModel::where('id', 'in', $whosealArr)->where('is_del', 0)->column('id,total_amount,status as order_status,currency,total_amount as order_total_amount,pay_amount as order_pay_amount,owner');
        $wholesalDict = [];
        foreach ($wholesalData as $item) {
            $wholesalDict[$item['id']] = $item;
            // 收集owner的ID
            if (!empty($item['owner'])) {
                $operatorIds[] = $item['owner'];
            }
        }


        foreach ($data as &$jer) {
            if ($jer['transfer_voucher_id']) {
                $jer['transfer_voucher_url'] = array_reduce(explode(',', $jer['transfer_voucher_id']), function ($carry, $item) use ($imgsDict) {
                    $carry[] = $imgsDict[$item] ?? '';
                    return $carry;
                }, []);
            }
            if ($jer['order_type'] == 'wholesal') {
                $jer['order_status'] = isset($wholesalDict[$jer['order_id']]['order_status']) ? $wholesalDict[$jer['order_id']]['order_status'] : '';
                $jer['total_amount'] = isset($wholesalDict[$jer['order_id']]['total_amount']) ? $wholesalDict[$jer['order_id']]['total_amount'] : '';
                $jer['owner'] = isset($wholesalDict[$jer['order_id']]['owner']) ? $wholesalDict[$jer['order_id']]['owner'] : '';

                $jer['order_total_amount'] = isset($wholesalDict[$jer['order_id']]['order_total_amount']) ? $wholesalDict[$jer['order_id']]['order_total_amount'] : '';
                $jer['order_pay_amount'] = isset($wholesalDict[$jer['order_id']]['order_pay_amount']) ? $wholesalDict[$jer['order_id']]['order_pay_amount'] : '';
                $jer['currency'] = isset($wholesalDict[$jer['order_id']]['currency']) ? $wholesalDict[$jer['order_id']]['currency'] : '';
            } elseif ($jer['order_type'] == 'order') {
                $jer['order_status'] = isset($orderDict[$jer['order_id']]['order_status']) ? $orderDict[$jer['order_id']]['order_status'] : '';
                $jer['total_amount'] = isset($orderDict[$jer['order_id']]['total_amount']) ? $orderDict[$jer['order_id']]['total_amount'] : '';
                $jer['owner'] = isset($orderDict[$jer['order_id']]['owner']) ? $orderDict[$jer['order_id']]['owner'] : '';

                $jer['order_total_amount'] = isset($orderDict[$jer['order_id']]['order_total_amount']) ? $orderDict[$jer['order_id']]['order_total_amount'] : '';
                $jer['order_pay_amount'] = isset($orderDict[$jer['order_id']]['order_pay_amount']) ? $orderDict[$jer['order_id']]['order_pay_amount'] : '';
                $jer['currency'] = isset($orderDict[$jer['order_id']]['currency']) ? $orderDict[$jer['order_id']]['currency'] : '';
            }
            $jer['user_name'] = $jer['user_name'] . '(' . $jer['user_email'] . ')';
            unset($jer['user_email']);
        }

        $arrData['data'] = ['list' => $data, 'total' => $total];
        return $arrData;
    }

    /**
     * 获取字段
     * @param $field
     * @return array
     * 2024-11-13 14 31 17
     * author: jiang
     */
    public function resource($field)
    {
        $model = new OrderPaymentModel();
        $res = $model->getFieldEnum($field);
        return [
            'code' => 0,
            'data' => $res,
            'message' => '成功'
        ];
    }
    /**
     * 撤销上传支付凭证
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-11-13 19 20 56
     * author: jiang
     */
    public function cancellVoucher($param)
    {
        $existsPayment = OrderPaymentModel::whereIn('status', ['00'])->where('id', '=', $param['id'])->field('id')->find();
        if (!$existsPayment) {
            return [
                'code' => 1,
                'message' => '状态已变更，无法撤销'
            ];
        }
        $update = OrderPaymentModel::whereIn('status', ['00'])->where('id', '=', $param['id'])->delete();
        if (!$update) {
            return ['code' => 1, 'message' => '撤销失败'];
        }
        $this->logger->logOperation($existsPayment->order_id, 'order', '订单-支付凭证撤销', '支付凭证上传撤销', 1, 'order_payment', $existsPayment->id);
        return ['code' => 0, 'message' => '操作成功'];
    }
    /**
     * 审核
     * @param $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2024-11-13 19 20 56
     * author: jiang
     */
    public function examine($param)
    {
        if ($param['is_approved'] == 0 && $param['remark'] == null) {
            return ['code' => 1, 'message' => '请填写驳回原因'];
        }
        // 验证汇款编码唯一性
        if (!empty($param['voucher_code']) && $param['is_approved'] == 1) {
            $voucher_code = trim($param['voucher_code']);
            $existsPayment = OrderPaymentModel::where('voucher_code', $voucher_code)->whereIn('status', ['01'])->where('id', '!=', $param['id'])->field('id')->find();
            if ($existsPayment) {
                return ['code' => 1, 'message' => '汇款编码已经被使用'];
            }
        }


        // 查找订单支付记录
        $orderPayment = OrderPaymentModel::where('status', '00')->find($param['id']);

        if (!$orderPayment) {
            return ['code' => 1, 'message' => '订单支付记录不存在'];
        }

        // 联表查询订单及客户信息，避免多次查询
        $order = OrderModel::with(['items', 'customer'])
            ->find($orderPayment->order_id);

        if (!$order) {
            return ['code' => 1, 'message' => '订单不存在'];
        }

        if (!$order->customer) {
            return ['code' => 1, 'message' => '客户信息不存在'];
        }

        // 验证订单商品
        $items = $order->items;
        if (empty($items)) {
            return ['code' => 1, 'message' => '订单商品不存在'];
        }

        $initial_order_pay_status = $order->pay_status;

        $orderPaymentAttr = $orderPayment->getSelfAttr();

        Db::startTrans();
        try {
            if ($param['paid_amount'] && $param['paid_amount'] != $orderPayment->paid_amount) {
                $orderPayment->paid_amount = $param['paid_amount']; //支付金额
            }
            if ($param['voucher_code'] && $param['voucher_code'] != $orderPayment->voucher_code) {
                $orderPayment->voucher_code = $param['voucher_code']; //交易单号
            }
            $orderPayment->status = $param['is_approved'] == 1 ? '01' : '04';
            $orderPayment->remark = $param['remark'];
            $orderPayment->reviewer = $param['operator_id'];
            $orderPayment->reviewer_time = date('Y-m-d H:i:s');
            $orderPayment->payment_method = $param['payment_method'] ?? 3;
            $orderPayment->payment_method_name = $orderPaymentAttr['payment_method'][$param['payment_method']] ?? '';

            $orderPayment->transfer_recepit_id = count($param['transfer_recepit_id']) > 0 ? implode(',', $param['transfer_recepit_id']) : null;
            if (!empty($param['hash'])) {
                $orderPayment->hash = $param['hash'];
            }

            if (!$orderPayment->save()) {
                throw new \Exception('审核失败');
            }
            if ($param['is_approved'] == 1) { // 审核通过
                if ($param['fee_type'] == 2) { // 物流费用补充 不改变订单状态
                    $order->logistics_fee = $order->logistics_fee + $param['paid_amount'];
                    $order->total_amount = $order->total_amount + $param['paid_amount'];
                } elseif ($param['fee_type'] == 3) {
                    //                    $order->pay_amount = $order->pay_amount + $param['paid_amount'];
                    $order->total_amount = $order->total_amount + $param['paid_amount'];
                } else {
                    // 判断支付金额 是否达到订单金额
                    if ($order->total_amount <= ($order->pay_amount + $param['paid_amount'])) {
                        $order->pay_status = 3;
                        if ($order->order_category == 'wholesal') {
                            $order->status = 100;
                        } elseif ($order->order_category == 'order') {
                            $order->status = 30;
                        }
                        if ($order->order_type !== 2) {
                            foreach ($items as $value) {
                                // 完全支付后 更新库存盘点
                                Warehouse::productSoldStat($value['product_id'], $value['warehouse_id'], 0, $value['quantity'], $value['quantity']);
                            }
                        }

                        $Business = new BusinessLog();
                        $Business->logOperation($order->id, $orderPayment->order_type, '支付成功', $order->order_no);
                        // 更新客户信息
                        if ($order->customer->stage != 3) {
                            $order->customer->stage = 3;
                            if (!$order->customer->save()) {
                                throw new \Exception('更新客户信息失败');
                            }
                        }
                    } else {
                        $order->pay_status = 4;
                    }
                }

                $order->pay_amount = $order->pay_amount + $param['paid_amount'];
                if (!$order->save()) {
                    throw new \Exception('订单状态更新失败');
                }
            }

            Db::commit();

            // 通知
            try {
                // 基本参数验证
                if (!isset($param['is_approved'])) {
                    throw new \Exception('缺少支付审批状态参数');
                }
                if ($param['is_approved'] != 1 && empty($param['remark'])) {
                    throw new \Exception('驳回原因不能为空');
                }

                $notificationService = new CompleteNotificationService();
                $order_info =  $order->toArray();
                // 确定通知事件和内容
                if ($param['is_approved'] == 1) {
                    $event = $order->pay_status == 3 ? 'order_payment' : 'order_partial_payment';
                    $content = '';
                } else {
                    $event = 'order_payment_reject';
                    $operator = \app\admin\model\Operator::where('id', $param['operator_id'])->value('cname');
                    $order_info['title']  = $operator . '驳回了您的付款单';
                    //                    $content = '订单号: ' . $order->order_no . ' 支付被驳回，驳回原因: ' . $param['remark'] . '，请及时处理';
                    $content = '订单号: ' . $order->order_no . " \n\n 订单序号：{$order->id} \n\n 驳回原因: {$param['remark']}  \n\n  ";
                }

                // 处理待发货状态
                if ($order->status == 30) {
                    $notificationService->send('order_delivery_pending', $order->toArray(), [], '', '50,51');
                }

                // 获取客户信息和通知接收者
                $customer = CustomerModel::where('id', $order->user_id)->find();
                $orderPartner = $order->partner ? array_filter(explode(',', $order->partner)) : [];
                $recipients = array_filter(array_unique([
                    $customer->owner ?? null,
                    $order->owner ?? null,
                    $order->signatory ?? null,
                    ...$orderPartner
                ]));

                // 发送通知
                $notificationService->send($event, $order_info, $recipients, $content);
            } catch (\Exception $e) {
                Log::error('订单支付通知发送失败: ' . $e->getMessage() . ' 订单编号: ' . $order->order_no . ' | 文件：' . $e->getFile() . ' | 行号：' . $e->getLine());
            }
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'message' => $e->getMessage()];
        }

        // 锁定库存
        if (in_array($initial_order_pay_status, [1, 2]) && in_array($order->pay_status, [3, 4]) && 2 !== $order->order_type && $param['is_approved'] == 1) { // 只有初始订单支付状态为未支付时，才锁定库存
            $inventory = new CommonInventoryService();
            $lockResult = $inventory->lockInventory(['id' => $order->id, 'operator_id' => $param['operator_id']]);
            if (!$lockResult) {
                Db::startTrans();
                try {
                    $order->review_node = 1;
                    $order->exceptionstatus = $order->exceptionstatus ? $order->exceptionstatus . ',1' : 1;
                    $order->save();
                    Db::name('order_item')->where('order_id', $order->id)->update(['exceptionstatus' => 1]);
                    Db::commit();
                } catch (\Exception $e) {
                    Log::error('支付凭证审核锁定库存失败,修改订单异常状态失败, order_id: ' . $order->id . ' 错误信息: ' . $e->getMessage());
                    Db::rollback();
                }

                $operator = DB::name('operator')
                    ->where('is_del', 0)
                    ->where(function ($query) {
                        $query->whereRaw("FIND_IN_SET('40', job)")
                            ->whereOr(function ($subQuery) {
                                $subQuery->whereRaw("FIND_IN_SET('41', job)");
                            })
                            ->whereOr(function ($subQuery) {
                                $subQuery->whereRaw("FIND_IN_SET('50', job)");
                            })
                            ->whereOr(function ($subQuery) {
                                $subQuery->whereRaw("FIND_IN_SET('51', job)");
                            });
                    })
                    ->column('id');
                if (!empty($operator)) {
                    $domain = config('domain')[env('APP_ENV')]['erphome'];
                    if ($order->order_category == 'wholesal') {
                        $url  = $domain . '/#/order/wholesal-order-management';
                    } else {
                        $url = $domain . '/#/order/order-management';
                    }
                    $dingTalk = new DingTalk();
                    $dingTalk->SendActionCardJobNotificationMessage(
                        '支付凭证审核锁定库存失败',
                        '支付凭证审核锁定库存失败, 订单编号: ' . $order->order_no,
                        $url,
                        $operator,
                    );
                }
                Log::error('支付凭证审核锁定库存失败, order_id: ' . $order->id);
            }
        }

        $mailService = new MailService();
        if ($order->pay_status == 3) {
            /* 修改GoAffPro订单状态 */
            $GoAffPro = new GoAffPro();
            $GoAffPro->updateAffiliateOrder(true, $order->id);
            $mailService->send('order_payment', $order->toArray());
        } else {
            $mailService->send('order_partial_payment', $order->toArray());
        }
        $approverWhere = [
            'child_entity_id' => $orderPayment->id,
            'business_module' => 'order',
            'child_business_module' => 'order_payment',
            'operate' => '订单-支付凭证上传',

        ];
        $this->logger->updateApprover($approverWhere, $param['operator_id']);
        if ($param['is_approved'] == 1) {
            $this->logger->logOperation($orderPayment->order_id, 'order', '订单-支付凭证审核通过', '付款单审核通过', 1, 'order_payment', $orderPayment->id);
        } else {
            $this->logger->logOperation($orderPayment->order_id, 'order', '订单-支付凭证审核驳回', '付款单审核驳回', 1, 'order_payment', $orderPayment->id);
        }
        return ['code' => 0, 'message' => '操作成功'];
    }
    // public function examineOld($param) // 旧的审核方法
    // {

    //     $str_hash = null;
    //     if (!empty($param['hash'])) {
    //         $str_hash = trim($param['hash']);
    //         $orderPayment = OrderPaymentModel::where('hash', $str_hash)->field('id')->find();
    //         if ($orderPayment) {
    //             return ['code' => 1, 'message' => '汇款编码已经被使用'];
    //         }
    //     }

    //     $oOrderPaymentModel = OrderPaymentModel::where('status', '00')->find($param['id']);
    //     if (!$oOrderPaymentModel) {
    //         return ['code' => 1, 'message' => 'order_type 订单不存在'];
    //     }

    //     $model = null;
    //     switch ($oOrderPaymentModel->order_type) {
    //         case 'wholesal':
    //             $model = new WholesalOrderModel();
    //             break;
    //         case 'order':
    //             $model = new OrderModel();
    //             break;
    //     }

    //     if (!$model) {
    //         return ['code' => 1, 'message' => '订单类型错误'];
    //     }
    //     $order = $model->find($oOrderPaymentModel->order_id);
    //     if (!$order) {
    //         return ['code' => 1, 'message' => '订单不存在'];
    //     }
    //     // 查询客户信息
    //     $oCustomer = CustomerModel::where('id', $order->user_id)->find();
    //     if (!$oCustomer) {
    //         return ['code' => 1, 'message' => '客户不存在'];
    //     }

    //     // 修改锁定库存
    //     $items = $order->items->toArray();
    //     if (empty($items)) {
    //         return ['code' => 1, 'message' => '订单商品不存在'];
    //     }
    //     $condition = [];
    //     foreach ($items as $item) {
    //         $condition[] = [
    //             'productid' => $item['product_id'],
    //             'wid' => $item['warehouse_id'],
    //             'arrival_date' => $item['arrival_date'],
    //             'is_futures' => $item['is_futures'],
    //             'quantity' => $item['quantity']
    //         ];
    //     }
    //     $oProductInventory = new ProductInventory();
    //     $result = $oProductInventory->inventory($condition);

    //     if ($result['code'] === 1) {
    //         return $result;
    //     }
    //     $data = $result['data'];
    //     if (!$data) {
    //         return ['code' => 1, 'message' => '未找到库存数据'];
    //     }
    //     $inventorySet = [];
    //     foreach ($data as $value) {
    //         if ($value['exceptionstatus'] == 1 && $order->order_type !== 2) {
    //             return ['code' => 1, 'message' => '库存不足'];
    //         }
    //         foreach ($value['items'] as $val) {
    //             $inventorySet[$val['id']] = $val['pay_quantity'];
    //         }
    //     }

    //     // 获取库存信息
    //     $oInventoryModel = InventoryModel::whereIn('id', array_keys($inventorySet))->select();
    //     foreach ($oInventoryModel as $inv) {
    //         if ($inv->available_qty - $inv->locked_qty < $inv->pay_quantity && $inv->allow_zero_stock_sale !== 1 && $order->order_type !== 2) {
    //             $inv->exceptionstatus = 1;
    //             $inv->save();
    //             return ['code' => 1, 'message' => '库存不足'];
    //         }
    //     }

    //     Db::startTrans();
    //     try {
    //         if ($param['paid_amount'] && $param['paid_amount'] != $oOrderPaymentModel->paid_amount) {
    //             $oOrderPaymentModel->paid_amount = $param['paid_amount']; //支付金额
    //         }
    //         if ($param['voucher_code'] && $param['voucher_code'] != $oOrderPaymentModel->voucher_code) {
    //             $oOrderPaymentModel->voucher_code = $param['voucher_code']; //交易单号
    //         }
    //         $oOrderPaymentModel->status = '01';
    //         $oOrderPaymentModel->reviewer = $param['operator_id'];
    //         $oOrderPaymentModel->reviewer_time = date('Y-m-d H:i:s');

    //         if ($str_hash) {
    //             $oOrderPaymentModel->hash = $str_hash;
    //         }

    //         if (!$oOrderPaymentModel->save()) {
    //             throw new \Exception('审核失败');
    //         }

    //         // 获取库存信息
    //         if ($order->order_type !== 2 && $order->pay_status === 1) {
    //             foreach ($oInventoryModel as $inv) {
    //                 // 锁定库存
    //                 //                $inv->lock_qty = $inv->lock_qty + $inventorySet[$inv->id] ?? 0;
    //                 $inv->inc('lock_qty', $inventorySet[$inv->id] ?? 0);
    //                 if (!$inv->save()) {
    //                     throw new \Exception('库存锁定失败');
    //                 }
    //             }
    //         }

    //         // 判断支付金额 是否达到订单金额
    //         if ($order->total_amount <= ($order->pay_amount + $param['paid_amount'])) {
    //             $order->pay_status = 3;
    //             if ($oOrderPaymentModel->order_type == 'wholesal') {
    //                 $order->status = 100;
    //             } elseif ($oOrderPaymentModel->order_type == 'order') {
    //                 $order->status = 30;
    //             }
    //             if ($order->order_type !== 2) {
    //                 foreach ($items as $value) {
    //                     // 完全支付后 更新库存盘点
    //                     Warehouse::productSoldStat($value['product_id'], $value['warehouse_id'], 0, $value['quantity'], $value['quantity']);
    //                 }
    //             }

    //             $Business = new BusinessLog();
    //             $Business->logOperation($order->id, $oOrderPaymentModel->order_type, '支付成功', $order->order_no);
    //             // 更新客户信息
    //             if ($oCustomer->stage != 3) {
    //                 $oCustomer->stage = 3;
    //                 if (!$oCustomer->save()) {
    //                     throw new \Exception('更新客户信息失败');
    //                 }
    //             }
    //         } else {
    //             $order->pay_status = 4;
    //         }
    //         $order->pay_amount = $order->pay_amount + $param['paid_amount'];
    //         if (!$order->save()) {
    //             throw new \Exception('订单状态更新失败');
    //         }
    //         Db::commit();
    //     } catch (\Exception $e) {
    //         Db::rollback();
    //         return ['code' => 1, 'message' => $e->getMessage()];
    //     }
    //     $mailService = new MailService();
    //     if ($order->pay_status == 3) {
    //         /* 修改GoAffPro订单状态 */
    //         $GoAffPro = new GoAffPro();
    //         $GoAffPro->updateAffiliateOrder(true, $order->id);
    //         $mailService->send('order_payment', $order->toArray());
    //     } else {
    //         $mailService->send('order_partial_payment', $order->toArray());
    //     }
    //     $this->logger->logOperation($oOrderPaymentModel->id, 'orderPayment', '审核', '付款单审核');
    //     return ['code' => 0, 'message' => '审核成功'];
    // }

    /**
     *  上传支付凭证
     */
    public function voucher($param)
    {
        switch ($param['order_type']) {
            case 'order':
                $order = OrderModel::find($param['order_id']);
                break;
            case 'wholesal':
                $order = WholesalOrderModel::find($param['order_id']);
                break;
            default:
                return ['code' => 1, 'message' => 'order_type 参数错误'];
        }

        /* 订单是否存在 */
        if (!$order) {
            return ['code' => 1, 'message' => '订单不存在'];
        }

        /* 无法支付 & 审核 */
        if ($order->status != 10 && $order->status != 21 && 1 == $param['fee_type']) {
            return ['code' => 1, 'message' => '订单状态无法服务上传凭证'];
        }





        $orderPayment = new OrderPaymentModel();
        $orderPaymentAttr = $orderPayment->getSelfAttr();

        $PaymenCount = OrderPaymentModel::where('order_id', $order->id)->where('status', '00')->where('payment_method', 3)->field('id')->count();
        if ($PaymenCount > 9) {
            return ['code' => 1, 'message' => '上传凭证数量已达上限'];
        }

        $data = [];
        $data['order_id'] = $order->id;
        $data['payment_method'] = $param['payment_method'] ?? 3;
        $data['payment_method_name'] = $orderPaymentAttr['payment_method'][$param['payment_method']] ?? '';
        $data['pay_type'] = '00';
        $data['creator'] = $param['creator'];
        $data['pay_time'] = date("Y-m-d H:i:s", time());
        $data['pay_currency'] = $order->currency;
        $data['user_id'] = $order->user_id;
        $data['order_no'] = $order->order_no;
        $data['order_type'] = $param['order_type'];
        $data['notes'] = $param['notes'];
        $data['create_time'] = date("Y-m-d H:i:s", time());
        $data['status'] = '00';
        $data['transfer_voucher_id'] =  implode(',', $param['voucher_id']);
        $data['pay_amount'] = $order->total_amount - $order->pay_amount;
        $data['voucher_code'] = $param['voucher_code'];
        $data['paid_amount'] = $param['paid_amount'];
        $data['fee_type'] = $param['fee_type'];
        $data['transfer_type'] = $param['transfer_type'];

        $reslut = OrderPaymentModel::create($data);
        $order->transfer_type = $param['transfer_type'];

        # 汇款单通知
        $data = $order->toArray();
        $operator = \app\admin\model\Operator::where('id', $param['creator'])->value('cname');
        $data['operator'] = $operator;
        $data['payment_method_name'] = $orderPaymentAttr['payment_method'][$param['payment_method']] ?? '';
        $data['voucher_pay_amount'] = $param['paid_amount'];
        $data['voucher_code'] = $param['voucher_code'];
        $notificationService = new CompleteNotificationService();
        $notificationService->send('order_upload_payment_voucher', $data);

        if ($order->pay_status == 1) {
            $order->pay_status = 2; // 待审核
            if (null == $order->pay_time) { // 记录订单首次支付时间
                $order->pay_time = date('Y-m-d H:i:s');
            }
            $order->updater = $param['operator_id'];
            $order->update_time = date("Y-m-d H:i:s");
            if (!$order->save()) {
                return ['code' => 1, 'message' => '订单状态更新失败'];
            }
        }

        if ($reslut) {
            $recipientsJob = '';
            switch ($data['transfer_type']) {
                case 1: // Blockchain
                case 6: //第三方代收
                    $recipientsJob = '1,10'; //  BOSS 运营主管
                    break;
                case 2: // Bank Transfer
                case 3: // 银行对公
                case 4: //  微信
                case 5: //  支付宝
                    $recipientsJob = '1,20,21'; // BOSS  财务主管 财务人员
                    break;
                default:
                    $recipientsJob = '1,10,20,21'; //  BOSS 运营主管 财务主管 财务
                    break;
            }
            $this->logger->logOperation($order->id, 'order', '订单-支付凭证上传', '支付凭证上传待审核', 1, 'order_payment', $reslut->id, $recipientsJob);
            return ['code' => 0, 'message' => '上传成功', 'data' => ['id' => $reslut->id]];
        } else {
            return ['code' => 1, 'message' => '上传失败'];
        }
    }


    /**
     * @describe 获取订单相关支付列表
     * @author: Bobo
     * @date: 2025-08-06 14:44:55
     * @param [type] @required
     * @return Renderable
     */
    public function orderRelatedPaymentList($param)
    {
        $order_payment = OrderPaymentModel::where('order_id', $param['order_id'])
            ->field('id,payment_method_name,pay_account,pay_time,pay_amount,voucher_code,pay_voucher,creator,create_time,reviewer,reviewer_time,transfer_voucher_id,transfer_type,notes,pay_code,pay_currency,payment_url,paid_amount,update_time,fee_type, 0 as is_returnorder_payment')
            ->where('status', '01')
            ->where('pay_type', '00')
            ->with(['reviewer', 'creator'])
            ->select();



        $already_returnorder_payment = OrderPaymentModel::name('returnorder_payback')
            ->where('is_del', 0)
            ->whereIn('payment_id', $order_payment->column('id'))
            ->select();

        if ($already_returnorder_payment->count() > 0) {
            foreach ($order_payment as &$value) {
                if (in_array($value['id'], $already_returnorder_payment->column('payment_id'))) {
                    $value['is_returnorder_payment'] = 1;
                }
            }
        }
        return ['code' => 0, 'message' => '获取成功', 'data' => $order_payment];
    }

    /**
     * 导出支付订单数据到Excel
     * @param $param
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 2025-01-27
     * author: assistant
     */
    public function exportOrderPayment($param)
    {
        // 1. 构建查询条件（复用index方法的查询逻辑）
        $where = [];

        if ($param['order_no']) {
            $where[] = ['order_no', 'like', '%' . $param['order_no'] . '%'];
        }
        if ($param['voucher_code']) {
            $where[] = ['voucher_code', 'like', '%' . $param['voucher_code'] . '%'];
        }
        if ($param['order_type']) {
            $where[] = ['order_type', '=', $param['order_type']];
        }
        if ($param['pay_type']) {
            $where[] = ['pay_type', '=', $param['pay_type']];
        }
        if ($param['pay_status']) {
            $where[] = ['status', '=', $param['pay_status']];
        }
        if ($param['start_time']) {
            $where[] = ['pay_time', '>=', $param['start_time']];
        }
        if ($param['end_time']) {
            $where[] = ['pay_time', '<', $param['end_time']];
        }
        if ($param['invoice_status']) {
            $where[] = ['invoice_status', 'in', $param['invoice_status']];
        }
        if ($param['user_id']) {
            $where[] = ['user_id', 'in', $param['user_id']];
        }
        if ($param['creator']) {
            $where[] = ['creator', '=', $param['creator']];
        }

        // 2. 查询数据并关联必要模型
        $field = ['id', 'order_no', 'order_id', 'user_id', 'status', 'pay_amount', 'paid_amount', 'status as pay_status', 'pay_type', 'pay_currency', 'notes', 'pay_account', 'pay_code', 'payment_url', 'reviewer_time', 'pay_time', 'voucher_code', 'reviewer', 'order_type', 'transfer_voucher_id', 'payment_method', 'fee_type', 'transfer_type', 'creator', 'remark'];
        $orderPayments = OrderPaymentModel::where($where)
            ->with(['user'])
            ->field($field)
            ->order('id', 'desc')
            ->select();

        $data = $orderPayments->toArray();

        // 3. 处理关联数据（复用index方法的逻辑）
        $orderArr = [];
        $whosealArr = [];
        $imgsArr = [];
        $operatorIds = []; // 收集所有操作员ID

        foreach ($data as $value) {
            if ($value['order_type'] == 'wholesal') {
                $whosealArr[] = $value['order_id'];
            } elseif ($value['order_type'] == 'order') {
                $orderArr[] = $value['order_id'];
            }
            if ($value['transfer_voucher_id']) {
                $imgsArr = array_merge($imgsArr, explode(',', $value['transfer_voucher_id']));
            }
            // 收集操作员ID
            if (!empty($value['creator'])) {
                $operatorIds[] = $value['creator'];
            }
        }

        $imgsArr = array_unique($imgsArr);
        $oImages = Images::whereIn('id', $imgsArr)->column('id,url');
        $imgsDict = [];
        foreach ($oImages as $item) {
            $imgsDict[$item['id']] = 'https://' . config('filesystem.aliyun-oss.bucket') . '.' . config('filesystem.aliyun-oss.endpoint') . '/' . $item['url'];
        }

        $orderData = OrderModel::where('id', 'in', $orderArr)->where('is_del', 0)->column('id,total_amount,status as order_status,currency,total_amount as order_total_amount,pay_amount as order_pay_amount,owner');
        $orderDict = [];
        foreach ($orderData as $item) {
            $orderDict[$item['id']] = $item;
            // 收集owner的ID
            if (!empty($item['owner'])) {
                $operatorIds[] = $item['owner'];
            }
        }
        $oOrderModel = new OrderModel();

        $wholesalData = WholesalOrderModel::where('id', 'in', $whosealArr)->where('is_del', 0)->column('id,total_amount,status as order_status,currency,total_amount as order_total_amount,pay_amount as order_pay_amount,owner');
        $wholesalDict = [];
        foreach ($wholesalData as $item) {
            $wholesalDict[$item['id']] = $item;
            // 收集owner的ID
            if (!empty($item['owner'])) {
                $operatorIds[] = $item['owner'];
            }
        }

        // 4. 准备枚举映射
        $model = new OrderPaymentModel();
        $enumMaps = [
            'payment_method' => $model->getAttributes('payment_method'),
            'pay_type' => $model->getAttributes('pay_type'),
            'status' => $model->getAttributes('status'),
            'transfer_type' => $model->getAttributes('transfer_type'),
            'fee_type' => $model->getAttributes('fee_type'),
            'order_type' => $model->getAttributes('order_type'),
        ];

        // 收集所有需要查询的币种ID
        $currencyIds = [];
        foreach ($data as $payment) {
            if (!empty($payment['pay_currency'])) {
                $currencyIds[] = $payment['pay_currency'];
            }
        }

        // 从订单数据中收集币种ID
        foreach ($orderDict as $order) {
            if (!empty($order['currency'])) {
                $currencyIds[] = $order['currency'];
            }
        }
        foreach ($wholesalDict as $wholesal) {
            if (!empty($wholesal['currency'])) {
                $currencyIds[] = $wholesal['currency'];
            }
        }

        // 去重并查询币种映射
        $currencyIds = array_unique(array_filter($currencyIds));
        $currencyMap = [];
        if (!empty($currencyIds)) {
            $currencyMap = TransactionCurrency::where('is_del', 0)
                ->whereIn('id', $currencyIds)
                ->column('name', 'id');
        }

        $orderStatusEnum = $oOrderModel->getFieldEnum('status', 'array')['status'] ?? [];

        // 查询操作员信息
        $operatorIds = array_unique(array_filter($operatorIds));
        $operatorMap = [];
        if (!empty($operatorIds)) {
            $operatorMap = \app\admin\model\Operator::where('is_del', 0)
                ->whereIn('id', $operatorIds)
                ->column('cname', 'id');
        }

        // 5. 处理数据并格式化为导出结构
        $exportData = [];
        foreach ($data as $payment) {
            // 处理关联数据
            if ($payment['transfer_voucher_id']) {
                $payment['transfer_voucher_url'] = array_reduce(explode(',', $payment['transfer_voucher_id']), function ($carry, $item) use ($imgsDict) {
                    $carry[] = $imgsDict[$item] ?? '';
                    return $carry;
                }, []);
            }

            if ($payment['order_type'] == 'wholesal') {
                $payment['order_status'] = isset($wholesalDict[$payment['order_id']]['order_status']) ? $wholesalDict[$payment['order_id']]['order_status'] : '';
                $payment['total_amount'] = isset($wholesalDict[$payment['order_id']]['total_amount']) ? $wholesalDict[$payment['order_id']]['total_amount'] : '';
                $payment['owner'] = isset($wholesalDict[$payment['order_id']]['owner']) ? $wholesalDict[$payment['order_id']]['owner'] : '';
                $payment['order_currency'] = isset($wholesalDict[$payment['order_id']]['currency']) ? $wholesalDict[$payment['order_id']]['currency'] : '';
            } elseif ($payment['order_type'] == 'order') {
                $payment['order_status'] = isset($orderDict[$payment['order_id']]['order_status']) ? $orderDict[$payment['order_id']]['order_status'] : '';
                $payment['total_amount'] = isset($orderDict[$payment['order_id']]['total_amount']) ? $orderDict[$payment['order_id']]['total_amount'] : '';
                $payment['owner'] = isset($orderDict[$payment['order_id']]['owner']) ? $orderDict[$payment['order_id']]['owner'] : '';
                $payment['order_currency'] = isset($orderDict[$payment['order_id']]['currency']) ? $orderDict[$payment['order_id']]['currency'] : '';
            }

            // 格式化用户名称显示
            $userName = '';
            if (isset($payment['user_name']) && isset($payment['user_email'])) {
                $userName = $payment['user_name'] . '(' . $payment['user_email'] . ')';
            } elseif (isset($payment['user_name'])) {
                $userName = $payment['user_name'];
            }

            $exportData[] = [
                $payment['id'], // 序号
                $enumMaps['payment_method'][$payment['payment_method']] ?? $payment['payment_method'], // 交易方式
                $payment['voucher_code'] ?? '', // 交易流水号
                $payment['pay_time'] ?? '', // 支付时间
                $operatorMap[$payment['creator']] ?? '', // 创建人
                $operatorMap[$payment['owner']] ?? '', // 负责人
                $enumMaps['fee_type'][$payment['fee_type']] ?? $payment['fee_type'], // 费用类型
                $enumMaps['transfer_type'][$payment['transfer_type']] ?? $payment['transfer_type'], // 汇款方式
                $payment['total_amount'] ?? '', // 订单金额
                $currencyMap[$payment['order_currency']] ?? $payment['order_currency'], // 订单币种 - 从订单表获取
                $orderStatusEnum[$payment['order_status']] ?? '', // 订单状态
                $payment['paid_amount'] ?? '', // 付款金额
                $currencyMap[$payment['pay_currency']] ?? $payment['pay_currency'], // 付款币种
                $enumMaps['status'][$payment['status']] ?? $payment['status'], // 付款状态
                $payment['order_no'] ?? '', // 订单编码
                $enumMaps['order_type'][$payment['order_type']] ?? $payment['order_type'], // 订单类型
                $userName, // 用户
                $enumMaps['pay_type'][$payment['pay_type']] ?? $payment['pay_type'], // 支付类型
                $payment['notes'] ?? '', // 备注
                $payment['remark'] // 驳回原因
            ];
        }

        // 6. 设置Excel标题头（根据图片要求）
        $header = [
            "序号",
            "交易方式",
            "交易流水号",
            "支付时间",
            "创建人",
            "负责人",
            "费用类型",
            "汇款方式",
            "订单金额",
            "订单币种",
            "订单状态",
            "付款金额",
            "付款币种",
            "付款状态",
            "订单编码",
            "订单类型",
            "用户",
            "支付类型",
            "备注",
            "驳回原因"
        ];

        // 7. 导出Excel
        $fileName = 'Payment_' . date('YmdHis') . '.xlsx';
        ExcelService::export($exportData, $header, $fileName);
    }
}
